<?php

namespace App\Http\Controllers\App\V1;

use App\Exceptions\ApiErrCode;
use App\Http\Controllers\ApiController;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Services\Utils\Guard;
use App\Services\Utils\SkinRunSkinDetect;
use App\Services\Utils\LanguageChecker;
use App\Services\Utils\OSSable;
use App\Models\SkinRecords;
use App\Models\SkinRunRecords;
use Illuminate\Support\Carbon;

class UserSkinDetectController extends ApiController
{
    use OSSable;


    const ROUTES=[
        'index' => 'app.v1.userSkin.index',
        'store' => 'app.v1.userSkin.store',
        'create' => 'app.v1.userSkin.create',
        'show' => 'app.v1.userSkin.show',
        'update' =>'app.v1.userSkin.update',
        'destroy' =>'app.v1.userSkin.destroy',
        'edit' =>'app.v1.userSkin.edit'
    ];

    private $skinRunDetector;
    
    public function __construct()
    {
        $token =\env('SKINRUN_TOKEN');
        $version =\env('SKINRUN_VERSION');
        $url =\env('SKINRUN_URL');
        $this->skinRunDetector = new SkinRunSkinDetect($token, $version, $url);
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        // 起始时间
        $star_time = $request->get('start_time');
        $end_time = $request->get('end_time');
        if($star_time==null || $star_time=="")
            $star_time=Carbon::create('1970-01-01 00:00:00')
                                ->setTimezone('utc')
                                ->toDateTimeString();
        if($end_time==null || $end_time=="")
            $end_time=Carbon::now()
                            ->setTimezone('utc')
                            ->toDateTimeString();
        // 语言
        $language='zh-CN';
        if(!$request->has('language'))
        {
            $language='zh-CN';
        }else{
            $language = $request->input('language');
            $language=LanguageChecker::languageConvert($language);
        }
        $user = Guard::user();
        // 分页的话每页的数据
        $skinRecordColls=$user->userSkinRecords();
        $perPage = $request->per_page ?? \count($skinRecordColls->get());
        if((int)$perPage <=0)
            $perPage=\count($skinRecordColls->get());
        $page = $request->page ?? 1;
        if((int)$page <=0)
            $page=1;

        $code = 200;
        $message = "操作成功";
        $paginator = $skinRecordColls->whereBetween('created_at',[$star_time,$end_time])
                                     ->latest('created_at')
                                     ->paginate($perPage);
        $data=[];
        $detecor; // 肤质检测方法
        foreach($paginator->items() as $item)
        {
            $item_detail;
            switch($item->record_type)
            {
                case "skinrun":
                    $item_detail=SkinRunRecords::where('id',$item->record_id)->first();
                    $detecor=$this->skinRunDetector;
                    break;
            }
            $data[]=$detecor->analysisDetectResult($item, $item_detail, $language);
        } 
        $respone = new \stdClass();
        $respone->current_page=$paginator->currentPage();
        $respone->last_page=$paginator->lastPage();
        $respone->data=$data;
        $respone->total=$paginator->total();
        
        
        return json_encode(['code'=>$code, 'error'=>$message, 'data'=>$respone]);
    }


    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function indexList(Request $request)
    {
        $code = 200;
        $error = "操作成功";
        $user = Guard::user();
        $data=[];
        $skinRecordArray=$user->userSkinRecords()
                              ->latest('created_at')
                              ->get()
                              ->toArray();
        $data=$skinRecordArray;
        return json_encode(['code'=>$code, 'error'=>$error, 'data'=>$data]);
    }


    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $code = 200;
        $message = null;
        $data = null;
        if(!$request->has('image') || !$request->has('gender') || !$request->has('birthday'))
        {
            $code = 7001;
            $message = "image, gender, birthday为必填参数";
            return json_encode(['code'=>$code, 'error'=>$message, 'data'=>$data]);
        }
        $image = $request->file('image');
        if(\is_null($image))
        {
            $code = 7002;
            $message = "文件为空";
            return json_encode(['code'=>$code, 'error'=>$message, 'data'=>$data]);
        }
        if(!$image->isValid())
        {
            $code = 7003;
            $message = "文件上传失败";
            return json_encode(['code'=>$code, 'error'=>$message, 'data'=>$data]);
        }
        $fileext=$image->getClientOriginalExtension();
        $allowExts=array('png','jpg','jpeg');
        if(!in_array($fileext, $allowExts))
        {
            $code = 7003;
            $message = "只允许使用png,jpg,jpeg的图片格式";
            return json_encode(['code'=>$code, 'error'=>$message, 'data'=>$data]);
        }
        
        $gender = $request->input('gender');
        $birthday = $request->input('birthday');
        $detectType = $request->input('detect_type');
        $detecor; // 肤质检测方法

        // 语言
        $language='zh-CN';
        if(!$request->has('language'))
        {
            $language='zh-CN';
        }else{
            $language = $request->input('language');
            $language=LanguageChecker::languageConvert($language);
        }

        switch($detectType)
        {
            case 'skinrun':
                $detecor =$this->skinRunDetector;
                break;
            default:
                $detectType='skinrun';
                $detecor =$this->skinRunDetector;
                break;
        }
        
        $image_osskey=$this->uploadSkinImage($image);
        $image_url=$this->getStaticUrl($image_osskey);
        $skinResut= \json_decode($detecor->detect($image_url, $gender, $birthday));
        if($skinResut->code!=200)
        {
            $code = $skinResut->code;
            $message = $skinResut->message;
            // 检测失败删除缓存数据
            $this->deleteOSSKey($image_osskey);
            return json_encode(['code'=>$code, 'error'=>$message, 'data'=>$data]);
        }

        $user = Guard::user();
        $skinRecordArray= $this->saveUserSkinDetectRecord($user,$detectType,$skinResut->data, $image_osskey);
        
        $data=$detecor->analysisDetectResult($skinRecordArray[0], $skinRecordArray[1], $language);
        $message="操作成功";
        return json_encode(['code'=>$code, 'error'=>$message, 'data'=>$data]);
    }


    private function uploadSkinImage($skin_image, $prefix='user/skin_detect_img/')
    {
        return $this->uploadPostFile($skin_image, $prefix);
    }

    /**
     * 储存用户的肤质检测数据
     * @param user 用户
     * @param detect_type 肤质检测的类型
     * @param skinData 肤质检测的结果
     * @param image_key 存储在oss的图片的key
     */
    private function saveUserSkinDetectRecord($user, $detect_type, $skinData, $image_key)
    {
        $now = Carbon::now();
        $skinRecord;
        $record;
        $skinRecordArray = SkinRecords::where('user_id',$user->id)
                                    ->whereDate('created_at', $now)
                                    ->latest('created_at')
                                    ->get();
        if(\count($skinRecordArray)>0)
        {
            $skinRecord=$skinRecordArray[0];
            if($skinRecord->record_type=='skinrun')
            {
                $record=SkinRunRecords::find($skinRecord->record_id);
                $record->delete();
            }
        }else{
            $skinRecord= new SkinRecords;

        }

        if($detect_type=='skinrun')
        {
            $record = new SkinRunRecords;
            $record->image = $image_key;
            $record->pore = $skinData->pore;
            $record->wrinkle = $skinData->wrinkle;
            $record->stain = $skinData->stain;
            $record->acne = $skinData->acne;
            $record->eyes = $skinData->eyes;
            $record->oil_u = $skinData->oil_u;
            $record->oil_t = $skinData->oil_t;
            $record->skin_age = $skinData->skin_age;
            $record->skin_score = $skinData->skin_score;
            $record->skin_type = $skinData->skin_type;
        }
        $record->save();

        $skinRecord->user_id = $user->id;
        $skinRecord->record_type = $detect_type;
        $skinRecord->record_id = $record->id;
        $skinRecord->created_at = $now->timestamp;
        $skinRecord->updated_at = $now->timestamp;
        $skinRecord->save();

        return array($skinRecord, $record);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show(Request $request,$id)
    {
        //
        $code=200;
        $error="操作成功";
        $data=[];
        $time=null;
        
        $language='zh-CN';
        if(!$request->has('language'))
        {
            $language='zh-CN';
        }else{
            $language = $request->input('language');
            $language=LanguageChecker::languageConvert($language);
        }

        if($request->has('date'))
        {
            try{
                $time = Carbon::createFromFormat('Y-m-d', $request->get('date'), $tz='UTC');
            }catch(\Exception $err){
                $code=ApiErrCode::REQUEST_DATA_ERROR;
                $error='日期格式有误';
                return json_encode(['code'=>$code, 'error'=>$error, 'data'=>$data]);
            }
        }
        $skinRecords=null;
        if(!\is_null($time))
        {
            $user=Guard::user();
            $skinRecord=$user->userSkinRecords()->whereDate('created_at', '=', $time)->latest('created_at')->get();
        }else{
            $skinRecord=SkinRecords::where('id', $id)->get();
        }

        if(\count($skinRecord)<=0)
        {
            return json_encode(['code'=>$code, 'error'=>$error, 'data'=>$data]);
        }

        foreach($skinRecord as $item)
        {
            // return \json_encode($item);
            $item_detail;
            switch($item->record_type)
            {
                case "skinrun":
                    $item_detail=SkinRunRecords::where('id',$item->record_id)->first();
                    $detecor=$this->skinRunDetector;
                    break;
            }
            $data[]=$detecor->analysisDetectResult($item, $item_detail, $language);
        }
        return json_encode(['code'=>$code, 'error'=>$error, 'data'=>$data]);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}
